home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 50
/
Aminet 50 (2002)(GTI - Schatztruhe)[!][Aug 2002].iso
/
Aminet
/
util
/
libs
/
mpega_libmad.lha
/
mpega_libmad
/
library_init.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-12-18
|
25KB
|
897 lines
#include "library_init.h"
#include <exec/memory.h>
#include <exec/resident.h>
#include <exec/initializers.h>
#include "wrap_mpega.h"
#ifdef BUILD_POWERUP
#include <proto/ppc.h>
#include "support_pup.h"
#elif defined(BUILD_WARPUP)
#include <powerpc/powerpc.h>
#include <proto/powerpc.h>
#include "support.h"
#else
#include "support.h"
#endif
#ifdef BUILD_WARPUP
#define CallPPCFunc(func, p1, p2) \
({struct PPCArgs args; \
args.PP_Flags = PPF_LINEAR; \
args.PP_Stack = NULL; \
args.PP_StackSize = 0; \
args.PP_Code = (APTR)func; \
args.PP_Offset = 0; \
args.PP_Regs[0] = (ULONG)p1; \
args.PP_Regs[1] = (ULONG)p2; \
RunPPC(&args); \
args.PP_Regs[0]; \
})
struct MPEGABase
{
struct Library lib;
};
#pragma libbase MPEGABase
const char LibVersionString[] = "$VER: " LIB_ID;
const char LibNameString[] = LIB_NAME;
void INIT_3_InitLibraries(__REGA6(struct Library *base))
{
/* At least v15.0 is needed for PPF_LINEAR */
if (PowerPCBase->lib_Version >= 15) {
if (CallPPCFunc(InitSupport, 0, 0))
return;
}
abortLibInit();
}
void EXIT_3_InitLibraries(__REGA6(struct Library *base))
{
if (PowerPCBase->lib_Version >= 15)
CallPPCFunc(RemoveSupport, 0, 0);
}
#else
/* Reserved library-function and dummy entrypoint */
LONG LIB_Reserved(void)
{
return 0;
}
struct ExecBase *SysBase;
struct DosLibrary *DOSBase;
ULONG LibVectors[] = {
#ifdef __MORPHOS__
FUNCARRAY_32BIT_NATIVE,
#endif
(ULONG) &LIB_Open,
(ULONG) &LIB_Close,
(ULONG) &LIB_Expunge,
(ULONG) &LIB_Reserved,
(ULONG) &LIB_MPEGA_open,
(ULONG) &LIB_MPEGA_close,
(ULONG) &LIB_MPEGA_decode_frame,
(ULONG) &LIB_MPEGA_seek,
(ULONG) &LIB_MPEGA_time,
(ULONG) &LIB_MPEGA_find_sync,
(ULONG) &LIB_MPEGA_scale,
0xFFFFFFFF
};
struct LibInitStruct
{
ULONG LibSize;
void *FuncTable;
void *DataTable;
void (*InitFunc)(void);
};
struct LibInitStruct LibInitStruct = {
sizeof(struct PrivateBase),
LibVectors,
NULL,
(void (*)(void)) &LibInit
};
static const char LibVersion[] = "$VER: " LIB_ID;
static const struct Resident RomTag __attribute__((__aligned__(2))) = {
RTC_MATCHWORD,
&RomTag,
&RomTag + 1,
#ifdef __MORPHOS__
RTF_PPC | RTF_AUTOINIT,
#else
RTF_AUTOINIT,
#endif
LIB_VERSION,
NT_LIBRARY,
0,
LIB_NAME,
&LibVersion[6],
&LibInitStruct
};
#ifdef __MORPHOS__
ULONG __amigappc__ = 1;
#endif
static void LibCleanup(struct PrivateBase *PrivateBase)
{
#ifdef BUILD_POWERUP
RemoveSupport(PrivateBase);
#else
RemoveSupport();
#endif
if (DOSBase)
{
CloseLibrary((struct Library *)DOSBase);
PrivateBase->pv_DOSBase = DOSBase = NULL;
}
}
BPTR LibExpunge(struct PrivateBase *PrivateBase)
{
#ifdef BUILD_POWERUP
if (PrivateBase->ParentBase)
{
struct PrivateBase *OldBase = PrivateBase;
PrivateBase = PrivateBase->ParentBase;
FreeMem((APTR)((ULONG)(OldBase) - (ULONG)(OldBase->pv_Lib.lib_NegSize)),
OldBase->pv_Lib.lib_NegSize + OldBase->pv_Lib.lib_PosSize);
}
#endif
if ((PrivateBase->pv_Lib.lib_OpenCnt == 0))
{
BPTR seglist;
seglist = PrivateBase->pv_SegList;
Remove(&PrivateBase->pv_Lib.lib_Node);
LibCleanup(PrivateBase);
FreeMem((APTR)((ULONG)(PrivateBase) - (ULONG)(PrivateBase->pv_Lib.lib_NegSize)),
PrivateBase->pv_Lib.lib_NegSize + PrivateBase->pv_Lib.lib_PosSize);
return seglist;
} else PrivateBase->pv_Lib.lib_Flags |= LIBF_DELEXP;
return 0L;
}
#ifdef __MORPHOS__
struct Library *LibInit(struct PrivateBase *PrivateBase, BPTR SegList, struct ExecBase *sysbase)
#else
struct Library * ASM LibInit(REG(d0, struct PrivateBase *PrivateBase), REG(a0, BPTR SegList), REG(a6, struct ExecBase *sysbase))
#endif
{
SysBase = sysbase;
if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 36)))
{
#ifdef BUILD_POWERUP
if (InitSupport(PrivateBase))
#else
if (InitSupport())
#endif
{
PrivateBase->pv_Lib.lib_Revision = LIB_REVISION;
PrivateBase->pv_SegList = SegList;
PrivateBase->pv_SysBase = SysBase;
PrivateBase->pv_DOSBase = DOSBase;
#ifdef BUILD_POWERUP
PrivateBase->ParentBase = NULL;
#endif
return &PrivateBase->pv_Lib;
}
}
LibCleanup(PrivateBase);
return NULL;
}
#ifdef __MORPHOS__
struct Library *LIB_Open(void)
{
struct PrivateBase *PrivateBase = (struct PrivateBase *)REG_A6;
#else
struct Library * ASM LIB_Open(REG(a6, struct PrivateBase *PrivateBase))
{
#endif
#ifdef BUILD_POWERUP
if (PrivateBase->pv_Lib.lib_OpenCnt > 0)
{
struct PrivateBase *NewBase;
ULONG BaseSize = PrivateBase->pv_Lib.lib_NegSize + PrivateBase->pv_Lib.lib_PosSize;
if ((NewBase = AllocMem(BaseSize, MEMF_PUBLIC)))
{
CopyMem((APTR)((ULONG)PrivateBase - (ULONG)PrivateBase->pv_Lib.lib_NegSize), NewBase, BaseSize);
NewBase = (APTR)((ULONG)NewBase + (ULONG)PrivateBase->pv_Lib.lib_NegSize);
NewBase->ParentBase = PrivateBase;
NewBase->pv_CallPPCData = NULL;
NewBase->pv_CallPPCMsg = NULL;
NewBase->pv_StartupData = NULL;
NewBase->pv_StartupMsg = NULL;
NewBase->pv_ReplyPort = NULL;
NewBase->pv_PPCPort = NULL;
NewBase->pv_Task = NULL;
if (!InitDispatch(NewBase, MSGTYPE_HELLO))
{
LibExpunge(NewBase);
return NULL;
}
PrivateBase->pv_Lib.lib_Flags &= ~LIBF_DELEXP;
PrivateBase->pv_Lib.lib_OpenCnt++;
}
return &NewBase->pv_Lib;
} else {
if (!InitDispatch(PrivateBase, MSGTYPE_HELLO))
{
LibExpunge(PrivateBase);
return NULL;
}
#endif
PrivateBase->pv_Lib.lib_Flags &= ~LIBF_DELEXP;
PrivateBase->pv_Lib.lib_OpenCnt++;
return &PrivateBase->pv_Lib;
#ifdef BUILD_POWERUP
}
#endif
}
#ifdef __MORPHOS__
BPTR LIB_Close(void)
{
struct PrivateBase *PrivateBase = (struct PrivateBase *)REG_A6;
#else
BPTR ASM LIB_Close(REG(a6, struct PrivateBase *PrivateBase))
{
#endif
#ifdef BUILD_POWERUP
RemoveDispatch(PrivateBase, MSGTYPE_GOODBYE);
if (PrivateBase->ParentBase)
{
struct PrivateBase *OldBase = PrivateBase;
PrivateBase = PrivateBase->ParentBase;
FreeMem((APTR)((ULONG)(OldBase) - (ULONG)(OldBase->pv_Lib.lib_NegSize)),
OldBase->pv_Lib.lib_NegSize + OldBase->pv_Lib.lib_PosSize);
}
#endif
if (PrivateBase->pv_Lib.lib_OpenCnt > 0) PrivateBase->pv_Lib.lib_OpenCnt--;
if ((PrivateBase->pv_Lib.lib_OpenCnt == 0) && (PrivateBase->pv_Lib.lib_Flags & LIBF_DELEXP))
return LibExpunge(PrivateBase);
return 0L;
}
#ifdef __MORPHOS__
BPTR LIB_Expunge(void)
{
struct PrivateBase *PrivateBase = (struct PrivateBase *)REG_A6;
#else
BPTR ASM LIB_Expunge(REG(a6, struct PrivateBase *PrivateBase))
{
#endif
return LibExpunge(PrivateBase);
}
#endif /* BUILD_WARPUP */
#ifdef __MORPHOS__
MPEGA_STREAM *LIB_MPEGA_open(void)
{
char *stream_name = (char *)REG_A0;
MPEGA_CTRL *ctrl = (MPEGA_CTRL *)REG_A1;
struct PrivateBase *PrivateBase = (struct PrivateBase *)REG_A6;
struct Task *task = FindTask(NULL);
ULONG stacksize, stackused, stackreq = REQ_STACKSIZE;
NewGetTaskAttrsA(task, &stacksize, sizeof(stacksize), TASKINFOTYPE_STACKSIZE, NULL);
NewGetTaskAttrsA(task, &stackused, sizeof(stackused), TASKINFOTYPE_USEDSTACKSIZE, NULL);
if ((stacksize - stackused) < stackreq)
{
char *newstack;
if (!(newstack = AllocVec(stackreq, MEMF_PUBLIC))) return NULL;
PrivateBase->stackswap.stack.stk_Lower = newstack;
PrivateBase->stackswap.stack.stk_Upper = (ULONG)newstack + stackreq;
PrivateBase->stackswap.Args[0] = (ULONG)stream_name;
PrivateBase->stackswap.Args[1] = (ULONG)ctrl;
PrivateBase->stackswap.Return = NewPPCStackSwap(&PrivateBase->stackswap.stack, WRAP_MPEGA_open, &PrivateBase->stackswap.Args);
FreeVec(newstack);
} else {
PrivateBase->stackswap.Return = (ULONG)WRAP_MPEGA_open(stream_name, ctrl);
}
return (MPEGA_STREAM *)PrivateBase->stackswap.Return;
}
#else
MPEGA_STREAM * LIB LIB_MPEGA_open(REG(a0, char *stream_name), REG(a1, MPEGA_CTRL *ctrl), REG(a6, struct PrivateBase *PrivateBase))
{
#ifdef BUILD_POWERUP
struct CallPPCData *CallPPCData;
APTR ReplyPort;
APTR CallPPCMsg;
ULONG Return;
APTR ThisTask = FindTask(NULL);
APTR SigTask = ((struct MsgPort *)PrivateBase->pv_ReplyPort)->mp_SigTask; /* !!!HACK!!! */
/* Workaround for bad tasks that pass around the library base */
if (SigTask != ThisTask)
{
struct TagItem tmpTagList[1];
tmpTagList[0].ti_Tag = TAG_DONE;
ReplyPort = PPCCreatePort(tmpTagList);
CallPPCMsg = PPCCreateMessage(ReplyPort, sizeof(struct CallPPCData));
CallPPCData = PPCAllocVec(sizeof(struct CallPPCData), MEMF_PUBLIC);
} else {
CallPPCData = PrivateBase->pv_CallPPCData;
CallPPCMsg = PrivateBase->pv_CallPPCMsg;
ReplyPort = PrivateBase->pv_ReplyPort;
}
CallPPCData->Type = MSGTYPE_CALL;
CallPPCData->PPCLVO = PPCLVO_MPEGA_open;
CallPPCData->Args[0] = (ULONG)stream_name;
CallPPCData->Args[1] = (ULONG)ctrl;
PPCCacheClearE(NULL, 0xffffffff, CACRF_ClearD);
PPCSendMessage(PrivateBase->pv_PPCPort, CallPPCMsg, CallPPCData, sizeof(struct CallPPCData), 0x12345678);
PPCWaitPort(ReplyPort);
PPCGetMessage(ReplyPort);
Return = CallPPCData->Return;
if (SigTask != ThisTask)
{
PPCDeleteMessage(CallPPCMsg);
PPCDeletePort(ReplyPort);
PPCFreeVec(CallPPCData);
}
return (MPEGA_STREAM *)Return;
#elif defined(BUILD_WARPUP)
return (MPEGA_STREAM *)CallPPCFunc(WRAP_MPEGA_open, stream_name, ctrl);
#else
register struct PrivateBase *MyPrivateBase __asm("a3") = PrivateBase;
register char *stackptr __asm("sp");
struct Task *task;
long stackleft, stackreq = REQ_STACKSIZE;
__asm("":"=r"(stackptr)); /* force gcc to acknowledge usage of the sp register */
MyPrivateBase->stackswap.Args[0] = (ULONG)stream_name;
MyPrivateBase->stackswap.Args[1] = (ULONG)ctrl;
task = FindTask(NULL);
stackleft = stackptr - (char *)task->tc_SPLower;
if (stackleft < stackreq)
{
char *newstack;
if (!(newstack = AllocVec(stackreq, MEMF_PUBLIC))) return NULL;
MyPrivateBase->stackswap.stack.stk_Lower = newstack;
MyPrivateBase->stackswap.stack.stk_Pointer = newstack + stackreq;
MyPrivateBase->stackswap.stack.stk_Upper = (ULONG)MyPrivateBase->stackswap.stack.stk_Pointer;
StackSwap(&MyPrivateBase->stackswap.stack);
MyPrivateBase->stackswap.Return = (ULONG)WRAP_MPEGA_open((char *)MyPrivateBase->stackswap.Args[0], (MPEGA_CTRL *)MyPrivateBase->stackswap.Args[1]);
StackSwap(&MyPrivateBase->stackswap.stack);
FreeVec(newstack);
return (MPEGA_STREAM *)MyPrivateBase->stackswap.Return;
} else {
return WRAP_MPEGA_open((char *)MyPrivateBase->stackswap.Args[0], (MPEGA_CTRL *)MyPrivateBase->stackswap.Args[1]);
}
#endif
}
#endif
#ifdef __MORPHOS__
void LIB_MPEGA_close(void)
{
MPEGA_STREAM *mpega_stream = (MPEGA_STREAM *)REG_A0;
#else
void LIB LIB_MPEGA_close(REG(a0, MPEGA_STREAM *mpega_stream), REG(a6, struct PrivateBase *PrivateBase))
{
#endif
#ifdef BUILD_POWERUP
struct CallPPCData *CallPPCData;
APTR ReplyPort;
APTR CallPPCMsg;
APTR ThisTask = FindTask(NULL);
APTR SigTask = ((struct MsgPort *)PrivateBase->pv_ReplyPort)->mp_SigTask; /* !!!HACK!!! */
/* Workaround for bad tasks that pass around the library base */
if (SigTask != ThisTask)
{
struct TagItem tmpTagList[1];
tmpTagList[0].ti_Tag = TAG_DONE;
ReplyPort = PPCCreatePort(tmpTagList);
CallPPCMsg = PPCCreateMessage(ReplyPort, sizeof(struct CallPPCData));
CallPPCData = PPCAllocVec(sizeof(struct CallPPCData), MEMF_PUBLIC);
} else {
CallPPCData = PrivateBase->pv_CallPPCData;
CallPPCMsg = PrivateBase->pv_CallPPCMsg;
ReplyPort = PrivateBase->pv_ReplyPort;
}
CallPPCData->Type = MSGTYPE_CALL;
CallPPCData->PPCLVO = PPCLVO_MPEGA_close;
CallPPCData->Args[0] = (ULONG)mpega_stream;
PPCCacheClearE(NULL, 0xffffffff, CACRF_ClearD);
PPCSendMessage(PrivateBase->pv_PPCPort, CallPPCMsg, CallPPCData, sizeof(struct CallPPCData), 0x12345678);
PPCWaitPort(ReplyPort);
PPCGetMessage(ReplyPort);
if (SigTask != ThisTask)
{
PPCDeleteMessage(CallPPCMsg);
PPCDeletePort(ReplyPort);
PPCFreeVec(CallPPCData);
}
#elif defined(BUILD_WARPUP)
CallPPCFunc(WRAP_MPEGA_close, mpega_stream, 0);
#else
WRAP_MPEGA_close(mpega_stream);
#endif
}
#ifdef __MORPHOS__
LONG LIB_MPEGA_decode_frame(void)
{
MPEGA_STREAM *mpega_stream = (MPEGA_STREAM *)REG_A0;
WORD **pcm = (WORD **)REG_A1;
struct PrivateBase *PrivateBase = (struct PrivateBase *)REG_A6;
struct Task *task = FindTask(NULL);
ULONG stacksize, stackused, stackreq = REQ_STACKSIZE;
NewGetTaskAttrsA(task, &stacksize, sizeof(stacksize), TASKINFOTYPE_STACKSIZE, NULL);
NewGetTaskAttrsA(task, &stackused, sizeof(stackused), TASKINFOTYPE_USEDSTACKSIZE, NULL);
if ((stacksize - stackused) < stackreq)
{
char *newstack;
if (!(newstack = AllocVec(stackreq, MEMF_PUBLIC))) return MPEGA_ERR_MEM;
PrivateBase->stackswap.stack.stk_Lower = newstack;
PrivateBase->stackswap.stack.stk_Upper = (ULONG)newstack + stackreq;
PrivateBase->stackswap.Args[0] = (ULONG)mpega_stream;
PrivateBase->stackswap.Args[1] = (ULONG)pcm;
PrivateBase->stackswap.Return = NewPPCStackSwap(&PrivateBase->stackswap.stack, WRAP_MPEGA_decode_frame, &PrivateBase->stackswap.Args);
FreeVec(newstack);
} else {
PrivateBase->stackswap.Return = (ULONG)WRAP_MPEGA_decode_frame(mpega_stream, pcm);
}
return (LONG)PrivateBase->stackswap.Return;
}
#else
LONG LIB LIB_MPEGA_decode_frame(REG(a0, MPEGA_STREAM *mpega_stream), REG(a1, WORD *pcm[MPEGA_MAX_CHANNELS]), REG(a6, struct PrivateBase *PrivateBase))
{
#ifdef BUILD_POWERUP
struct CallPPCData *CallPPCData;
APTR ReplyPort;
APTR CallPPCMsg;
ULONG Return;
APTR ThisTask = FindTask(NULL);
APTR SigTask = ((struct MsgPort *)PrivateBase->pv_ReplyPort)->mp_SigTask; /* !!!HACK!!! */
/* Workaround for bad tasks that pass around the library base */
if (SigTask != ThisTask)
{
struct TagItem tmpTagList[1];
tmpTagList[0].ti_Tag = TAG_DONE;
ReplyPort = PPCCreatePort(tmpTagList);
CallPPCMsg = PPCCreateMessage(ReplyPort, sizeof(struct CallPPCData));
CallPPCData = PPCAllocVec(sizeof(struct CallPPCData), MEMF_PUBLIC);
} else {
CallPPCData = PrivateBase->pv_CallPPCData;
CallPPCMsg = PrivateBase->pv_CallPPCMsg;
ReplyPort = PrivateBase->pv_ReplyPort;
}
CallPPCData->Type = MSGTYPE_CALL;
CallPPCData->PPCLVO = PPCLVO_MPEGA_decode_frame;
CallPPCData->Args[0] = (ULONG)mpega_stream;
CallPPCData->Args[1] = (ULONG)pcm;
PPCCacheClearE(NULL, 0xffffffff, CACRF_ClearD);
PPCSendMessage(PrivateBase->pv_PPCPort, CallPPCMsg, CallPPCData, sizeof(struct CallPPCData), 0x12345678);
PPCWaitPort(ReplyPort);
PPCGetMessage(ReplyPort);
Return = CallPPCData->Return;
if (SigTask != ThisTask)
{
PPCDeleteMessage(CallPPCMsg);
PPCDeletePort(ReplyPort);
PPCFreeVec(CallPPCData);
}
return (LONG)Return;
#elif defined(BUILD_WARPUP)
return (LONG)CallPPCFunc(WRAP_MPEGA_decode_frame, mpega_stream, pcm);
#else
register struct PrivateBase *MyPrivateBase __asm("a3") = PrivateBase;
register char *stackptr __asm("sp");
struct Task *task;
long stackleft, stackreq = REQ_STACKSIZE;
__asm("":"=r"(stackptr)); /* force gcc to acknowledge usage of the sp register */
MyPrivateBase->stackswap.Args[0] = (ULONG)mpega_stream;
MyPrivateBase->stackswap.Args[1] = (ULONG)pcm;
task = FindTask(NULL);
stackleft = stackptr - (char *)task->tc_SPLower;
if (stackleft < stackreq)
{
char *newstack;
if (!(newstack = AllocVec(stackreq, MEMF_PUBLIC))) return MPEGA_ERR_MEM;
MyPrivateBase->stackswap.stack.stk_Lower = newstack;
MyPrivateBase->stackswap.stack.stk_Pointer = newstack + stackreq;
MyPrivateBase->stackswap.stack.stk_Upper = (ULONG)MyPrivateBase->stackswap.stack.stk_Pointer;
StackSwap(&MyPrivateBase->stackswap.stack);
MyPrivateBase->stackswap.Return = (ULONG)WRAP_MPEGA_decode_frame((MPEGA_STREAM *)MyPrivateBase->stackswap.Args[0], (WORD **)MyPrivateBase->stackswap.Args[1]);
StackSwap(&MyPrivateBase->stackswap.stack);
FreeVec(newstack);
return (LONG)MyPrivateBase->stackswap.Return;
} else {
return WRAP_MPEGA_decode_frame((MPEGA_STREAM *)MyPrivateBase->stackswap.Args[0], (WORD **)MyPrivateBase->stackswap.Args[1]);
}
#endif
}
#endif
#ifdef __MORPHOS__
LONG LIB_MPEGA_seek(void)
{
MPEGA_STREAM *mpega_stream = (MPEGA_STREAM *)REG_A0;
ULONG ms_time_position = (ULONG)REG_D0;
struct PrivateBase *PrivateBase = (struct PrivateBase *)REG_A6;
struct Task *task = FindTask(NULL);
ULONG stacksize, stackused, stackreq = REQ_STACKSIZE;
NewGetTaskAttrsA(task, &stacksize, sizeof(stacksize), TASKINFOTYPE_STACKSIZE, NULL);
NewGetTaskAttrsA(task, &stackused, sizeof(stackused), TASKINFOTYPE_USEDSTACKSIZE, NULL);
if ((stacksize - stackused) < stackreq)
{
char *newstack;
if (!(newstack = AllocVec(stackreq, MEMF_PUBLIC))) return MPEGA_ERR_MEM;
PrivateBase->stackswap.stack.stk_Lower = newstack;
PrivateBase->stackswap.stack.stk_Upper = (ULONG)newstack + stackreq;
PrivateBase->stackswap.Args[0] = (ULONG)mpega_stream;
PrivateBase->stackswap.Args[1] = (ULONG)ms_time_position;
PrivateBase->stackswap.Return = NewPPCStackSwap(&PrivateBase->stackswap.stack, WRAP_MPEGA_seek, &PrivateBase->stackswap.Args);
FreeVec(newstack);
} else {
PrivateBase->stackswap.Return = (ULONG)WRAP_MPEGA_seek(mpega_stream, ms_time_position);
}
return (LONG)PrivateBase->stackswap.Return;
}
#else
LONG LIB LIB_MPEGA_seek(REG(a0, MPEGA_STREAM *mpega_stream), REG(d0, ULONG ms_time_position), REG(a6, struct PrivateBase *PrivateBase))
{
#ifdef BUILD_POWERUP
struct CallPPCData *CallPPCData;
APTR ReplyPort;
APTR CallPPCMsg;
ULONG Return;
APTR ThisTask = FindTask(NULL);
APTR SigTask = ((struct MsgPort *)PrivateBase->pv_ReplyPort)->mp_SigTask; /* !!!HACK!!! */
/* Workaround for bad tasks that pass around the library base */
if (SigTask != ThisTask)
{
struct TagItem tmpTagList[1];
tmpTagList[0].ti_Tag = TAG_DONE;
ReplyPort = PPCCreatePort(tmpTagList);
CallPPCMsg = PPCCreateMessage(ReplyPort, sizeof(struct CallPPCData));
CallPPCData = PPCAllocVec(sizeof(struct CallPPCData), MEMF_PUBLIC);
} else {
CallPPCData = PrivateBase->pv_CallPPCData;
CallPPCMsg = PrivateBase->pv_CallPPCMsg;
ReplyPort = PrivateBase->pv_ReplyPort;
}
CallPPCData->Type = MSGTYPE_CALL;
CallPPCData->PPCLVO = PPCLVO_MPEGA_seek;
CallPPCData->Args[0] = (ULONG)mpega_stream;
CallPPCData->Args[1] = (ULONG)ms_time_position;
PPCCacheClearE(NULL, 0xffffffff, CACRF_ClearD);
PPCSendMessage(PrivateBase->pv_PPCPort, CallPPCMsg, CallPPCData, sizeof(struct CallPPCData), 0x12345678);
PPCWaitPort(ReplyPort);
PPCGetMessage(ReplyPort);
Return = CallPPCData->Return;
if (SigTask != ThisTask)
{
PPCDeleteMessage(CallPPCMsg);
PPCDeletePort(ReplyPort);
PPCFreeVec(CallPPCData);
}
return (LONG)Return;
#elif defined(BUILD_WARPUP)
return (LONG)CallPPCFunc(WRAP_MPEGA_seek, mpega_stream, ms_time_position);
#else
register struct PrivateBase *MyPrivateBase __asm("a3") = PrivateBase;
register char *stackptr __asm("sp");
struct Task *task;
long stackleft, stackreq = REQ_STACKSIZE;
__asm("":"=r"(stackptr)); /* force gcc to acknowledge usage of the sp register */
MyPrivateBase->stackswap.Args[0] = (ULONG)mpega_stream;
MyPrivateBase->stackswap.Args[1] = (ULONG)ms_time_position;
task = FindTask(NULL);
stackleft = stackptr - (char *)task->tc_SPLower;
if (stackleft < stackreq)
{
char *newstack;
if (!(newstack = AllocVec(stackreq, MEMF_PUBLIC))) return MPEGA_ERR_MEM;
MyPrivateBase->stackswap.stack.stk_Lower = newstack;
MyPrivateBase->stackswap.stack.stk_Pointer = newstack + stackreq;
MyPrivateBase->stackswap.stack.stk_Upper = (ULONG)MyPrivateBase->stackswap.stack.stk_Pointer;
StackSwap(&MyPrivateBase->stackswap.stack);
MyPrivateBase->stackswap.Return = (ULONG)WRAP_MPEGA_seek((MPEGA_STREAM *)MyPrivateBase->stackswap.Args[0], (ULONG)MyPrivateBase->stackswap.Args[1]);
StackSwap(&MyPrivateBase->stackswap.stack);
FreeVec(newstack);
return (LONG)MyPrivateBase->stackswap.Return;
} else {
return WRAP_MPEGA_seek((MPEGA_STREAM *)MyPrivateBase->stackswap.Args[0], (ULONG)MyPrivateBase->stackswap.Args[1]);
}
#endif
}
#endif
#ifdef __MORPHOS__
LONG LIB_MPEGA_time(void)
{
MPEGA_STREAM *mpega_stream = (MPEGA_STREAM *)REG_A0;
ULONG *ms_time_position = (ULONG *)REG_A1;
#else
LONG LIB LIB_MPEGA_time(REG(a0, MPEGA_STREAM *mpega_stream), REG(a1, ULONG *ms_time_position), REG(a6, struct PrivateBase *PrivateBase))
{
#endif
#ifdef BUILD_POWERUP
struct CallPPCData *CallPPCData;
APTR ReplyPort;
APTR CallPPCMsg;
ULONG Return;
APTR ThisTask = FindTask(NULL);
APTR SigTask = ((struct MsgPort *)PrivateBase->pv_ReplyPort)->mp_SigTask; /* !!!HACK!!! */
/* Workaround for bad tasks that pass around the library base */
if (SigTask != ThisTask)
{
struct TagItem tmpTagList[1];
tmpTagList[0].ti_Tag = TAG_DONE;
ReplyPort = PPCCreatePort(tmpTagList);
CallPPCMsg = PPCCreateMessage(ReplyPort, sizeof(struct CallPPCData));
CallPPCData = PPCAllocVec(sizeof(struct CallPPCData), MEMF_PUBLIC);
} else {
CallPPCData = PrivateBase->pv_CallPPCData;
CallPPCMsg = PrivateBase->pv_CallPPCMsg;
ReplyPort = PrivateBase->pv_ReplyPort;
}
CallPPCData->Type = MSGTYPE_CALL;
CallPPCData->PPCLVO = PPCLVO_MPEGA_time;
CallPPCData->Args[0] = (ULONG)mpega_stream;
CallPPCData->Args[1] = (ULONG)ms_time_position;
PPCCacheClearE(NULL, 0xffffffff, CACRF_ClearD);
PPCSendMessage(PrivateBase->pv_PPCPort, CallPPCMsg, CallPPCData, sizeof(struct CallPPCData), 0x12345678);
PPCWaitPort(ReplyPort);
PPCGetMessage(ReplyPort);
Return = CallPPCData->Return;
if (SigTask != ThisTask)
{
PPCDeleteMessage(CallPPCMsg);
PPCDeletePort(ReplyPort);
PPCFreeVec(CallPPCData);
}
return (LONG)Return;
#elif defined(BUILD_WARPUP)
return (LONG)CallPPCFunc(WRAP_MPEGA_time, mpega_stream, ms_time_position);
#else
return WRAP_MPEGA_time(mpega_stream, ms_time_position);
#endif
}
#ifdef __MORPHOS__
LONG LIB_MPEGA_find_sync(void)
{
UBYTE *buffer = (UBYTE *)REG_A0;
LONG buffer_size = (LONG)REG_D0;
#else
LONG LIB LIB_MPEGA_find_sync(REG(a0, UBYTE *buffer), REG(d0, LONG buffer_size), REG(a6, struct PrivateBase *PrivateBase))
{
#endif
#ifdef BUILD_POWERUP
struct CallPPCData *CallPPCData;
APTR ReplyPort;
APTR CallPPCMsg;
ULONG Return;
APTR ThisTask = FindTask(NULL);
APTR SigTask = ((struct MsgPort *)PrivateBase->pv_ReplyPort)->mp_SigTask; /* !!!HACK!!! */
/* Workaround for bad tasks that pass around the library base */
if (SigTask != ThisTask)
{
struct TagItem tmpTagList[1];
tmpTagList[0].ti_Tag = TAG_DONE;
ReplyPort = PPCCreatePort(tmpTagList);
CallPPCMsg = PPCCreateMessage(ReplyPort, sizeof(struct CallPPCData));
CallPPCData = PPCAllocVec(sizeof(struct CallPPCData), MEMF_PUBLIC);
} else {
CallPPCData = PrivateBase->pv_CallPPCData;
CallPPCMsg = PrivateBase->pv_CallPPCMsg;
ReplyPort = PrivateBase->pv_ReplyPort;
}
CallPPCData->Type = MSGTYPE_CALL;
CallPPCData->PPCLVO = PPCLVO_MPEGA_find_sync;
CallPPCData->Args[0] = (ULONG)buffer;
CallPPCData->Args[1] = (ULONG)buffer_size;
PPCCacheClearE(NULL, 0xffffffff, CACRF_ClearD);
PPCSendMessage(PrivateBase->pv_PPCPort, CallPPCMsg, CallPPCData, sizeof(struct CallPPCData), 0x12345678);
PPCWaitPort(ReplyPort);
PPCGetMessage(ReplyPort);
Return = CallPPCData->Return;
if (SigTask != ThisTask)
{
PPCDeleteMessage(CallPPCMsg);
PPCDeletePort(ReplyPort);
PPCFreeVec(CallPPCData);
}
return (LONG)Return;
#elif defined(BUILD_WARPUP)
return (LONG)CallPPCFunc(WRAP_MPEGA_find_sync, buffer, buffer_size);
#else
return WRAP_MPEGA_find_sync(buffer, buffer_size);
#endif
}
#ifdef __MORPHOS__
LONG LIB_MPEGA_scale(void)
{
MPEGA_STREAM *mpega_stream = (MPEGA_STREAM *)REG_A0;
LONG scale_percent = (LONG)REG_D0;
#else
LONG LIB LIB_MPEGA_scale(REG(a0, MPEGA_STREAM *mpega_stream), REG(d0, LONG scale_percent), REG(a6, struct PrivateBase *PrivateBase))
{
#endif
#ifdef BUILD_POWERUP
struct CallPPCData *CallPPCData;
APTR ReplyPort;
APTR CallPPCMsg;
ULONG Return;
APTR ThisTask = FindTask(NULL);
APTR SigTask = ((struct MsgPort *)PrivateBase->pv_ReplyPort)->mp_SigTask; /* !!!HACK!!! */
/* Workaround for bad tasks that pass around the library base */
if (SigTask != ThisTask)
{
struct TagItem tmpTagList[1];
tmpTagList[0].ti_Tag = TAG_DONE;
ReplyPort = PPCCreatePort(tmpTagList);
CallPPCMsg = PPCCreateMessage(ReplyPort, sizeof(struct CallPPCData));
CallPPCData = PPCAllocVec(sizeof(struct CallPPCData), MEMF_PUBLIC);
} else {
CallPPCData = PrivateBase->pv_CallPPCData;
CallPPCMsg = PrivateBase->pv_CallPPCMsg;
ReplyPort = PrivateBase->pv_ReplyPort;
}
CallPPCData->Type = MSGTYPE_CALL;
CallPPCData->PPCLVO = PPCLVO_MPEGA_scale;
CallPPCData->Args[0] = (ULONG)mpega_stream;
CallPPCData->Args[1] = (ULONG)scale_percent;
PPCCacheClearE(NULL, 0xffffffff, CACRF_ClearD);
PPCSendMessage(PrivateBase->pv_PPCPort, CallPPCMsg, CallPPCData, sizeof(struct CallPPCData), 0x12345678);
PPCWaitPort(ReplyPort);
PPCGetMessage(ReplyPort);
Return = CallPPCData->Return;
if (SigTask != ThisTask)
{
PPCDeleteMessage(CallPPCMsg);
PPCDeletePort(ReplyPort);
PPCFreeVec(CallPPCData);
}
return (LONG)Return;
#elif defined(BUILD_WARPUP)
return (LONG)CallPPCFunc(WRAP_MPEGA_scale, mpega_stream, scale_percent);
#else
return WRAP_MPEGA_scale(mpega_stream, scale_percent);
#endif
}